package com.yanghui.dtracing.core.opentracing;

import com.yanghui.dtracing.core.utils.NetUtils;
import com.yanghui.dtracing.core.utils.TracingUtil;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class RuleTraceGenerate implements TraceIdGenerate{

    private static AtomicInteger count = new AtomicInteger(999);

    @Override
    public String createTraceId() {
        StringBuilder result = new StringBuilder();
        String ipHex = this.ipToHex(NetUtils.getLocalIpv4());
        long timestamp = System.currentTimeMillis();
        int nextId = this.getNextId();
        String pid = TracingUtil.getPID();
//        System.out.println(ipHex + "||" + timestamp + "||" + nextId + "||" + pid);
        return result.append(ipHex).append(timestamp).append(nextId).append(pid).toString();
    }

    private String ipToHex(String ip){
        StringBuilder result = new StringBuilder();
        String[] ips = ip.split("\\.");
        for(String i : ips){
            String item = Integer.toHexString(Integer.valueOf(i));
            if(item.length() == 1){
                result.append("0" + item);
            }else {
                result.append(item);
            }
        }
        return result.toString();
    }

    private int getNextId() {
        for (;;) {
            int current = count.get();
            int next = (current > 9000) ? 1000 : current + 1;
            if (count.compareAndSet(current, next)) {
                return next;
            }
        }
    }

    public static void main(String[] args) throws Exception{
        ExecutorService pool = Executors.newFixedThreadPool(100);
        int c = 90000;
        Set<String> set = new CopyOnWriteArraySet<>();
        TraceIdGenerate generate = new DefaultTraceGenerate();
        for(int i=1;i<=c;i++){
            pool.execute(() -> {
                long start = System.currentTimeMillis();
                String id = generate.createTraceId();
//                System.out.println(id);
                long cost = System.currentTimeMillis() - start;
                if(cost >= 10){
                    System.out.println("耗时：" + (System.currentTimeMillis() - start));
                }
                if(!set.add(id)) {
                    System.out.println("重复：" + id);
                }
            });
        }
        Thread.sleep(30 * 1000);
        System.out.println("共：" + set.size());
        pool.shutdown();
    }
}
